package com.sunshine.timetable;

import android.content.Context;
import android.graphics.drawable.GradientDrawable;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.widget.Button;
import android.widget.LinearLayout;

import androidx.annotation.Nullable;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * 课表布局，
 * 请注意使用规则：先设置参数，然后init，然后addLesson
 */

public class TimetableView extends LinearLayout{

    /**
     * 高度为统一高度，宽度不可自定义
     */
    private int Heights = 300;

    /**
     * 课程button间的横纵向间距和内部的横纵间距
     */
    private int buttonWidthDistance = 10;
    private int buttonHeightDistance = 10;
    private int buttonWidthPadding = 5;
    private int buttonHeightPadding = 5;

    /**
     * Button透明度，字体大小，颜色，圆角等设置
     */
    private int buttonAlpha = (int) (255*0.5);
    private float lessonButtonTextSize = 11.0f;
    private float timeButtonTextSize = 11.0f;
    private int textColor = getResources().getColor(R.color.white);
    private int buttonRadius = 15;

    /**
     * 一天的课程数目，默认5节
     * 每周显示几天，用于是否显示周末
     */
    private int lessonCount = 5,dayCount = 5;

    /**
     * 显示周末，默认显示
     */
    private boolean showWeekend = true;

    /**
     * 显示非本周课程，默认为显示
     */
    private boolean showNotInThisWeekLesson = true;

    /**
     * 按钮上是否显示教师信息
     */
    private boolean showTeacher = true;

    /**
     * 本周，默认为第一周
     */
    private int thisWeek = 1;

    /**
     * 节数时间，是否显示节数时间
     */
    private String[] lessonTime = new String[]{"8:00\n9:50","10:10\n12:00","13:30\n15:20","15:40\n17:30","18:00\n19:30"};
    private boolean showLessonTime = true;

    /**
     * 用于显示课程信息的Button
     */
    private List<List<Button>> lessonesButton;

    /**
     * 用于存放课程名称的List
     */
    private List<List<StringBuilder>> lessonesText;

    /**
     * 日期栏Button的文字
     */
    private List<String> dateText = new ArrayList<>();
    private float dateButtonTextSize = 12.0f;

    /**
     * 获取今天日期和周几，来推算日期
     */
    private Calendar calendar = Calendar.getInstance();
    private int month = calendar.get(Calendar.MONTH)+1;
    private int dayOfWeek = getDayOfWeek();

    /**
     * 颜色池
     */
    private ColorUtils buttonBackground;

    private Context context;

    public TimetableView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        this.context = context;

        initTimetable();
    }

    /**
     *初始化课程表
     */
    public TimetableView initTimetable(){
        //获取根布局
        LayoutInflater inflater = LayoutInflater.from(context);
        inflater.inflate(R.layout.timetable,this);

        //设置是否显示周末
        if(isShowWeekend()){
            LayoutParams params = new LayoutParams(0,LayoutParams.MATCH_PARENT,3.0f);
            getRootView().findViewById(R.id.Sat_layout).setLayoutParams(params);
            getRootView().findViewById(R.id.Sun_layout).setLayoutParams(params);
            dayCount = 7;   //设置每周显示天数
        }else {
            LinearLayout.LayoutParams params = new LayoutParams(0,LayoutParams.MATCH_PARENT,0);
            getRootView().findViewById(R.id.Sat_layout).setLayoutParams(params);
            getRootView().findViewById(R.id.Sun_layout).setLayoutParams(params);
            dayCount = 5;
        }

        //设置Button间距
        LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
        params.setMargins(getButtonWidthDistance(),getButtonHeightDistance(),getButtonWidthDistance(),getButtonHeightDistance());

        //初始化ArrayList，尝试Button二维数组不能初始化
        lessonesButton = new ArrayList<>();
        for(int i = 0;i<dayCount;i++){
            List<Button> lesson = new ArrayList<>();
            for(int j = 0;j<lessonCount;j++){
                Button button = new Button(context);
                button.setHeight(getHeights());
                button.setLayoutParams(params);
                button.setText("");
                button.setTextColor(getTextColor());
                button.setTextSize(getLessonButtonTextSize());
                button.setPadding(getButtonWidthPadding(),getButtonHeightPadding(),getButtonWidthPadding(),getButtonHeightPadding());
                button.setBackgroundColor(0);//设置为透明但可点击
                lesson.add(button);
            }
            lessonesButton.add(lesson);
        }

        //将Button添加到父布局
        for (int i = 0; i < dayCount; i++) {
            chooseLessonDay(i).removeAllViews();//放这里来清除上次绘制的布局，否则initTimetable不会清除
            for (int j = 0; j < lessonCount; j++) {
                chooseLessonDay(i).addView(lessonesButton.get(i).get(j));
            }
        }

        buttonBackground = new ColorUtils(context);//创建颜色池对象

        lessonesText = new ArrayList<>();//初始化存放课程名称的list
        for(int day = 0;day<getDayCount();day++){
            List<StringBuilder> lessonText = new ArrayList<>();
            for(int quart = 0;quart<getLessonCount();quart++){
                lessonText.add(new StringBuilder());
            }
            lessonesText.add(lessonText);
        }

        //设置节数显示
        chooseLessonDay(-1).removeAllViews();
        for(int count = 1;count<=getLessonCount();count++){
            Button button = new Button(context);
            if(lessonTime.length == getLessonCount()&&isShowLessonTime()){
                button.setText(count+"\n\n"+lessonTime[count-1]);
            }else {
                button.setText(String.valueOf(count));
            }
            button.setTextSize(getTimeButtonTextSize());
            button.setTextColor(getTextColor());
            button.setHeight(getHeights());
            button.setPadding(0,0,0,0);
            button.setLayoutParams(params);
            button.setBackgroundColor(0);
            chooseLessonDay(-1).addView(button);
        }

        //日期栏设置
        setButtonText();
        for(int count = 1;count<=7;count++) chooseDateDay(count).removeAllViews();//玄幻代码，我也不知道为什么要移除一下view，反正移除完就对了
        if(showWeekend){
            LinearLayout.LayoutParams params_date = new LayoutParams(0,LayoutParams.MATCH_PARENT,3.0f);
            getRootView().findViewById(R.id.Sat_date_layout).setLayoutParams(params_date);
            getRootView().findViewById(R.id.Sun_date_layout).setLayoutParams(params_date);
            dayCount = 7;
        }else {
            LinearLayout.LayoutParams params_date = new LayoutParams(0,LayoutParams.MATCH_PARENT,0);
            getRootView().findViewById(R.id.Sat_date_layout).setLayoutParams(params_date);
            getRootView().findViewById(R.id.Sun_date_layout).setLayoutParams(params_date);
            dayCount = 5;
        }

        LayoutParams params_date = new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
        params_date.setMargins(10,10,10,10);
        for(int count = 0;count<=dayCount;count++){
            Button button = new Button(context);
            if(0==count){
                button.setText(month+"月");
            }else {
                button.setText(dateText.get(count-1)+"\n周"+getDayStringOfWeek(count));
            }
            if(count==getDayOfWeek()){
                GradientDrawable drawable=new GradientDrawable();
                drawable.setCornerRadius(15);
                drawable.setAlpha(buttonAlpha);
                drawable.setColor(new ColorUtils(context).setButtonBackground("date","0"));
                button.setBackground(drawable);
            }else {
                button.setBackgroundColor(0);
            }
            button.setPadding(0,0,0,0);
            button.setTextColor(textColor);
            button.setTextSize(getDateButtonTextSize());
            button.setLayoutParams(params_date);
            chooseDateDay(count).removeAllViews();
            chooseDateDay(count).addView(button);
        }
        return this;
    }

    /**
     * addLesson，重载支持传入list,各个参数
     * @param list
     */
    public TimetableView addLesson(List<List<String>> list) {
        String lessonName, teacher, room, time, color, week;

        //填充Button
        for (List<String> lesson : list) {
            //设置Button背景
            GradientDrawable drawable = new GradientDrawable();
            drawable.setCornerRadius(getButtonRadius());
            drawable.setAlpha(getButtonAlpha());

            lessonName = lesson.get(0);
            teacher = lesson.get(1);
            room = lesson.get(2);
            time = lesson.get(3);
            color = lesson.get(4);
            week = lesson.get(5);

            addLessonToView(lessonName, teacher, room, time, color, week);
        }
        return this;
    }

    public TimetableView addLesson(String lessonName, String teacher,String room,String time,String color,String week){
        addLessonToView(lessonName,teacher,room,time,color,week);
        return this;
    }

    public TimetableView deleteLesson(int day,int quart){
        getLessonesButton().get(day).get(quart).setText("");
        getLessonesButton().get(day).get(quart).setBackgroundColor(0);
        return this;
    }

    /**
     * get,set各个参数
     * @return
     */
    public int getHeights() {
        return Heights;
    }

    public TimetableView setHeights(int heights) {
        this.Heights = heights;
        return this;
    }

    public int getLessonCount() {
        return lessonCount;
    }

    public TimetableView setLessonCount(int lessonCount) {
        this.lessonCount = lessonCount;
        return this;
    }

    public boolean isShowWeekend() {
        return showWeekend;
    }

    public TimetableView setShowWeekend(boolean showWeekend) {
        this.showWeekend = showWeekend;
        return this;
    }

    public boolean isShowNotInThisWeekLesson() {
        return showNotInThisWeekLesson;
    }

    public TimetableView setShowNotInThisWeekLesson(boolean showNotInThisWeekLesson) {
        this.showNotInThisWeekLesson = showNotInThisWeekLesson;
        return this;
    }

    public int getButtonAlpha() {
        return buttonAlpha;
    }

    public TimetableView setButtonAlpha(int buttonAlpha) {
        this.buttonAlpha = buttonAlpha;
        return this;
    }

    public float getLessonButtonTextSize() {
        return lessonButtonTextSize;
    }

    public TimetableView setLessonButtonTextSize(float lessonButtonTextSize) {
        this.lessonButtonTextSize = lessonButtonTextSize;
        return this;
    }

    public int getTextColor() {
        return textColor;
    }

    public TimetableView setTextColor(int textColor) {
        this.textColor = textColor;
        return this;
    }

    public int getThisWeek() {
        return thisWeek;
    }

    public TimetableView setThisWeek(int thisWeek) {
        this.thisWeek = thisWeek;
        return this;
    }

    public List<List<Button>> getLessonesButton() {
        return lessonesButton;
    }

    public int getDayCount() {
        return dayCount;
    }

    public boolean isShowTeacher() {
        return showTeacher;
    }

    public TimetableView setShowTeacher(boolean showTeacher) {
        this.showTeacher = showTeacher;
        return this;
    }

    public String[] getLessonTime() {
        return lessonTime;
    }

    public TimetableView setLessonTime(String[] lessonTime) {
        this.lessonTime = lessonTime;
        return this;
    }

    public boolean isShowLessonTime() {
        return showLessonTime;
    }

    public TimetableView setShowLessonTime(boolean showLessonTime) {
        this.showLessonTime = showLessonTime;
        return this;
    }

    public int getButtonRadius() {
        return buttonRadius;
    }

    public TimetableView setButtonRadius(int buttonRadius) {
        this.buttonRadius = buttonRadius;
        return this;
    }

    public int getButtonWidthDistance() {
        return buttonWidthDistance;
    }

    public TimetableView setButtonWidthDistance(int buttonWidthDistance) {
        this.buttonWidthDistance = buttonWidthDistance;
        return this;
    }

    public int getButtonHeightDistance() {
        return buttonHeightDistance;
    }

    public TimetableView setButtonHeightDistance(int buttonHeightDistance) {
        this.buttonHeightDistance = buttonHeightDistance;
        return this;
    }

    public float getTimeButtonTextSize() {
        return timeButtonTextSize;
    }

    public TimetableView setTimeButtonTextSize(float timeButtonTextSize) {
        this.timeButtonTextSize = timeButtonTextSize;
        return this;
    }

    public float getDateButtonTextSize() {
        return dateButtonTextSize;
    }

    public TimetableView setDateButtonTextSize(float dateButtonTextSize) {
        this.dateButtonTextSize = dateButtonTextSize;
        return this;
    }

    public int getButtonWidthPadding() {
        return buttonWidthPadding;
    }

    public TimetableView setButtonWidthPadding(int buttonWidthPadding) {
        this.buttonWidthPadding = buttonWidthPadding;
        return this;
    }

    public int getButtonHeightPadding() {
        return buttonHeightPadding;
    }

    public TimetableView setButtonHeightPadding(int buttonHeightPadding) {
        this.buttonHeightPadding = buttonHeightPadding;
        return this;
    }

    public List<List<StringBuilder>> getLessonesText() {
        return lessonesText;
    }

    /**
     * 内部设置函数，选择周几，判断是否本周
     */

    private LinearLayout chooseLessonDay(int day){
        LinearLayout layout = null;
        switch (day){
            case -1:layout = getRootView().findViewById(R.id.time_layout);break;//时间显示器
            case 0:layout = getRootView().findViewById(R.id.Mon_layout);break;
            case 1:layout = getRootView().findViewById(R.id.Tues_layout);break;
            case 2:layout = getRootView().findViewById(R.id.Wed_layout);break;
            case 3:layout = getRootView().findViewById(R.id.Thur_layout);break;
            case 4:layout = getRootView().findViewById(R.id.Fri_layout);break;
            case 5:layout = getRootView().findViewById(R.id.Sat_layout);break;
            case 6:layout = getRootView().findViewById(R.id.Sun_layout);
        }
        return layout;
    }

    private LinearLayout chooseDateDay(int day){
        LinearLayout layout = null;
        switch (day){
            case 0:layout = getRootView().findViewById(R.id.month_layout);break;//时间显示器
            case 1:layout = getRootView().findViewById(R.id.Mon_date_layout);break;
            case 2:layout = getRootView().findViewById(R.id.Tues_date_layout);break;
            case 3:layout = getRootView().findViewById(R.id.Wed_date_layout);break;
            case 4:layout = getRootView().findViewById(R.id.Thur_date_layout);break;
            case 5:layout = getRootView().findViewById(R.id.Fri_date_layout);break;
            case 6:layout = getRootView().findViewById(R.id.Sat_date_layout);break;
            case 7:layout = getRootView().findViewById(R.id.Sun_date_layout);
        }
        return layout;
    }

    private boolean isThisWeek(String week) {
        String[] weeks1 = week.split(",");
        String[] weeks2 = week.split("-");
        if(weeks2.length==2){
            return Integer.parseInt(weeks2[0]) <= getThisWeek() && getThisWeek() <= Integer.parseInt(weeks2[1]);
        }else {
            for(String s:weeks1){
                if(s.equals(String.valueOf(getThisWeek()))) return true;
            }
        }
        return false;
    }

    private void addLessonToView(String lessonName, String teacher, String room, String time, String color, String week){
        int day,quart;
        GradientDrawable drawable=new GradientDrawable();

        day = Integer.parseInt(time.split("-")[0]) - 1;
        quart = Integer.parseInt(time.split("-")[1]) - 1;
        drawable.setCornerRadius(getButtonRadius());
        drawable.setAlpha(getButtonAlpha());

        lessonesText.get(day).get(quart).append(lessonName+"\n");

        if (lessonName.length() > 10 && getHeights() < 400 && getLessonButtonTextSize() >= 10) {
            lessonName = lessonName.substring(0, 10) + "...";
        }

        if (isThisWeek(week)) {
            if (isShowTeacher()) {
                lessonesButton.get(day).get(quart).setText(lessonName + "\n@" + room + "\n" + teacher);
            } else {
                lessonesButton.get(day).get(quart).setText(lessonName + "\n@" + room);
            }
            drawable.setColor(buttonBackground.setButtonBackground(lessonName, color));
            lessonesButton.get(day).get(quart).setBackground(drawable);
        } else if (isShowNotInThisWeekLesson() && lessonesButton.get(day).get(quart).getText().toString().equals("")) {
            lessonesButton.get(day).get(quart).setText("[非本周]\n" + lessonName);
            drawable.setColor(getResources().getColor(R.color.gray));
            lessonesButton.get(day).get(quart).setBackground(drawable);
        }

        //将Button添加到父布局
        for (int i = 0; i < dayCount; i++) {
            chooseLessonDay(i).removeAllViews();//放这里来清除上次绘制的布局，否则initTimetable不会清除
            for (int j = 0; j < lessonCount; j++) {
                chooseLessonDay(i).addView(lessonesButton.get(i).get(j));
            }
        }
    }

    /**
     * 内部设置函数，设置按钮文字，选择日期，获取周几Int String
     */
    private void setButtonText() {
        for(int i = 0;i<getDayCount();i++){
            SimpleDateFormat dateFormat = new SimpleDateFormat("MM/dd");
            Date beginDate = new Date();
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(beginDate);
            calendar.set(Calendar.DATE,calendar.get(Calendar.DATE)+(i-dayOfWeek+1));
            Date endDate = null;
            try {
                endDate = dateFormat.parse(dateFormat.format(calendar.getTime()));
            } catch (ParseException e) {
                e.printStackTrace();
            }
            dateText.add(dateFormat.format(endDate));
        }
    }

    private int getDayOfWeek(){
        int day = calendar.get(Calendar.DAY_OF_WEEK);
        switch (day){
            case 1:return 7;
            default:return day-1;
        }
    }

    //获取循环数组day的周几信息
    private String getDayStringOfWeek(int day){
        switch (day){
            case 1:return "一";
            case 2:return "二";
            case 3:return "三";
            case 4:return "四";
            case 5:return "五";
            case 6:return "六";
            case 7:return "日";
            default:return null;
        }
    }

}
